<template>
  <div class="upbtn">
    <div v-if="img !== ''" class="bg">
      <div v-if="config.ceilbutton" class="btndiv">
        <div
          class="btn"
          :style="`backgroundColor:${config.cancelButtonBackgroundColor};color:${config.cancelButtonTextColor}`"
          @click="canceltailor"
        >
          {{ config.cancelButtonText }}
        </div>
        <div class="img" @click="rotating" />
        <div
          class="btn"
          :style="`backgroundColor:${config.confirmButtonBackgroundColor};color:${config.confirmButtonTextColor}`"
          @click="tailoring"
        >
          {{ config.confirmButtonText }}
        </div>
      </div>
      <div class="wrapper">
        <vueCropper
          id="cropper"
          ref="cropper"
          :img="img"
          :output-size="config.outputSize"
          :output-type="config.outputType"
          :info="config.info"
          :can-scale="config.canScale"
          :auto-crop="config.autoCrop"
          :auto-crop-width="config.autoCropWidth"
          :auto-crop-height="config.autoCropHeight"
          :fixed="config.fixed"
          :fixed-number="config.fixedNumber"
          :full="config.full"
          :fixed-box="config.fixedBox"
          :can-move="config.canMove"
          :can-move-box="config.canMoveBox"
          :original="config.original"
          :center-box="config.centerBox"
          :high="config.high"
          :info-true="config.infoTrue"
          :max-img-size="config.maxImgSize"
          :enlarge="config.enlarge"
          :mode="config.mode"
          @cropMoving="moving($event)"
          @imgMoving="moving($event)"
        />
      </div>
      <div v-if="!config.ceilbutton" class="btndiv">
        <div
          class="btn"
          :style="`backgroundColor:${config.cancelButtonBackgroundColor};color:${config.cancelButtonTextColor}`"
          @click="canceltailor"
        >
          {{ config.cancelButtonText }}
        </div>
        <div class="img" @click="rotating" />
        <div
          class="btn"
          :style="`backgroundColor:${config.confirmButtonBackgroundColor};color:${config.confirmButtonTextColor}`"
          @click="tailoring"
        >
          {{ config.confirmButtonText }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
export default {
  name: 'H5Cropper',
  components: { VueCropper },
  props: {
    hideInput: {
      type: Boolean,
      default: false
    },
    option: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      img: '',
      config: {}
    }
  },
  watch: {
    option: {
      handler: function() {
        // do something
        delete this.option.autoCrop // TODO: 不开放权限
        if (
          typeof this.option.outputType === 'string' &&
          ['jpeg', 'png', 'webp'].indexOf(this.option.outputType) === -1
        ) {
          console.warn('Option.outputType is not [jpeg, png, webp]')
          delete this.option.outputType // TODO: 改回默认属性不影响调用
        }
        this.config = Object.assign(this.config, this.option)
      },
      deep: true
    }
  },
  created() {
    // Event getFile 需要明确 MIME 类型
    delete this.option.autoCrop // TODO: 不开放权限
    if (
      typeof this.option.outputType === 'string' &&
      ['jpeg', 'png', 'webp'].indexOf(this.option.outputType) === -1
    ) {
      console.warn('Option.outputType is not [jpeg, png, webp]')
      delete this.option.outputType // TODO: 改回默认属性不影响调用
    }

    this.config = Object.assign(
      {
        ceilbutton: false, // 顶部按钮，默认底部
        outputSize: 1, // 裁剪生成图片的质量
        outputType: 'png', // 裁剪生成图片的格式,默认png
        info: false, // 裁剪框的大小信息
        canScale: true, // 图片是否允许滚轮缩放
        autoCrop: false, // 是否默认生成截图框
        autoCropWidth: 0, // 默认生成截图框宽度
        autoCropHeight: 0, // 默认生成截图框高度
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [1, 1], // 截图框的宽高比例
        full: false, // 是否输出原图比例的截图
        fixedBox: true, // 固定截图框大小 不允许改变
        canMove: true, // 上传图片是否可以移动
        canMoveBox: false, // 截图框能否拖动
        original: false, // 上传图片按照原始比例渲染
        centerBox: true, // 截图框是否被限制在图片里面
        high: true, // 是否按照设备的dpr 输出等比例图片
        infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        maxImgSize: 2000, // 限制图片最大宽度和高度
        enlarge: 1, // 图片根据截图框输出比例倍数
        mode: '100%', // 图片默认渲染方式
        cancelButtonText: '取消', // 取消按钮文本
        confirmButtonText: '确定', // 确定按钮文本
        cancelButtonBackgroundColor: '#606266', // 取消按钮背景色
        confirmButtonBackgroundColor: '#0C64EB', // 确定按钮背景色
        cancelButtonTextColor: '#ffffff', // 取消按钮字体色
        confirmButtonTextColor: '#ffffff' // 确定按钮字体色
      },
      this.option
    )
  },
  methods: {
    // 取消裁剪
    canceltailor() {
      this.img = ''
      this.$emit('canceltailor')
    },
    // 选择照片
    async upphoto(e) {
      const photourl = e.target.files[0]
      this.$refs.headinput.value = null
      if (photourl) {
        this.$emit('imgorigoinf', photourl)
        this.img = await this.onloadimg(photourl)
        this.config.autoCrop = true
        setTimeout(() => {
          this.addsolide()
        }, 10)
      }
    },
    // 异步onload图片
    onloadimg(photourl) {
      return new Promise(function(resolve, reject) {
        const reader = new FileReader()
        reader.readAsDataURL(photourl)
        reader.onload = (e) => {
          resolve(e.target['result'])
        }
      })
    },
    // 确定裁剪
    tailoring() {
      // 获取截图的base64数据
      this.$refs.cropper.getCropData((data) => {
        this.$emit('getbase64Data', data)
        this.$emit('getbase64', data)
        this.img = ''
        this.config.autoCrop = false
      })
      // 获取截图的blob数据
      this.$refs.cropper.getCropBlob((data) => {
        this.$emit('getblobData', data)
        this.$emit('getblob', data)

        // Blob 转 File
        const suffix = {
          jpeg: 'jpg',
          png: 'png',
          webp: 'webp'
        }[this.config.outputType]
        const time = new Date().getTime()
        const file = new File([data], `${time}.${suffix}`, {
          type: `image/${this.config.outputType}`
        })

        this.$emit('getFile', file)
        this.$emit('get-file', file)

        this.img = ''
        this.config.autoCrop = false
      })
    },
    // 旋转照片
    rotating() {
      this.$refs.cropper.rotateRight()
      document.getElementsByClassName('cropper-modal')[0].style =
        'background-color: rgba(0,0,0,0.5);transition: 0.88s'
    },
    // 裁剪框移动
    moving(e) {
      //   console.log(e);
      if (e.moving) {
        document.getElementsByClassName('cropper-modal')[0].style =
          'background-color: rgba(0,0,0,0.5);transition: 0.88s'
      } else {
        document.getElementsByClassName('cropper-modal')[0].style =
          'background-color: rgba(0,0,0,0.8);transition: 0.88s'
      }
    },
    // 添加网格线
    addsolide() {
      if (document.getElementById('vertical') == null) {
        const box = document.getElementsByClassName('cropper-crop-box')[0]
        // 左网格线
        const verticalLeft = document.createElement('div')
        verticalLeft.id = 'vertical'
        verticalLeft.style.width = '1px'
        verticalLeft.style.height = '100%'
        verticalLeft.style.top = '0px'
        verticalLeft.style.left = '33%'
        verticalLeft.style.position = 'absolute'
        verticalLeft.style.backgroundColor = '#fff'
        verticalLeft.style.zIndex = '522'
        verticalLeft.style.opacity = '0.5'
        // 右网格线
        const verticalRight = document.createElement('div')
        verticalRight.style.width = '1px'
        verticalRight.style.height = '100%'
        verticalRight.style.top = '0px'
        verticalRight.style.right = '33%'
        verticalRight.style.position = 'absolute'
        verticalRight.style.backgroundColor = '#fff'
        verticalRight.style.zIndex = '522'
        verticalRight.style.opacity = '0.5'
        // 上网格线
        const verticalTop = document.createElement('div')
        verticalTop.style.width = '100%'
        verticalTop.style.height = '1px'
        verticalTop.style.top = '33%'
        verticalTop.style.left = '0px'
        verticalTop.style.position = 'absolute'
        verticalTop.style.backgroundColor = '#fff'
        verticalTop.style.zIndex = '522'
        verticalTop.style.opacity = '0.5'
        // 下网格线
        const verticalBottom = document.createElement('div')
        verticalBottom.style.width = '100%'
        verticalBottom.style.height = '1px'
        verticalBottom.style.bottom = '33%'
        verticalBottom.style.left = '0px'
        verticalBottom.style.position = 'absolute'
        verticalBottom.style.backgroundColor = '#fff'
        verticalBottom.style.zIndex = '522'
        verticalBottom.style.opacity = '0.5'
        // 左上边线
        const LeftTopSide = document.createElement('div')
        LeftTopSide.style.width = '30px'
        LeftTopSide.style.height = '4px'
        LeftTopSide.style.top = '-4px'
        LeftTopSide.style.left = '-4px'
        LeftTopSide.style.position = 'absolute'
        LeftTopSide.style.backgroundColor = '#fff'
        LeftTopSide.style.zIndex = '522'
        LeftTopSide.style.opacity = '1'
        // 上左边线
        const TopListSide = document.createElement('div')
        TopListSide.style.width = '4px'
        TopListSide.style.height = '30px'
        TopListSide.style.top = '-4px'
        TopListSide.style.left = '-4px'
        TopListSide.style.position = 'absolute'
        TopListSide.style.backgroundColor = '#fff'
        TopListSide.style.zIndex = '522'
        TopListSide.style.opacity = '1'
        // 右上边线
        const RightTopSide = document.createElement('div')
        RightTopSide.style.width = '30px'
        RightTopSide.style.height = '4px'
        RightTopSide.style.top = '-4px'
        RightTopSide.style.right = '-4px'
        RightTopSide.style.position = 'absolute'
        RightTopSide.style.backgroundColor = '#fff'
        RightTopSide.style.zIndex = '522'
        RightTopSide.style.opacity = '1'
        // 上右边线
        const TopRightSide = document.createElement('div')
        TopRightSide.style.width = '4px'
        TopRightSide.style.height = '30px'
        TopRightSide.style.top = '-4px'
        TopRightSide.style.right = '-4px'
        TopRightSide.style.position = 'absolute'
        TopRightSide.style.backgroundColor = '#fff'
        TopRightSide.style.zIndex = '522'
        TopRightSide.style.opacity = '1'
        // 左下边线
        const LeftBottomSide = document.createElement('div')
        LeftBottomSide.style.width = '30px'
        LeftBottomSide.style.height = '4px'
        LeftBottomSide.style.bottom = '-4px'
        LeftBottomSide.style.left = '-4px'
        LeftBottomSide.style.position = 'absolute'
        LeftBottomSide.style.backgroundColor = '#fff'
        LeftBottomSide.style.zIndex = '522'
        LeftBottomSide.style.opacity = '1'
        // 下左边线
        const BottomListSide = document.createElement('div')
        BottomListSide.style.width = '4px'
        BottomListSide.style.height = '30px'
        BottomListSide.style.bottom = '-4px'
        BottomListSide.style.left = '-4px'
        BottomListSide.style.position = 'absolute'
        BottomListSide.style.backgroundColor = '#fff'
        BottomListSide.style.zIndex = '522'
        BottomListSide.style.opacity = '1'
        // 右下边线
        const RightBottomSide = document.createElement('div')
        RightBottomSide.style.width = '30px'
        RightBottomSide.style.height = '4px'
        RightBottomSide.style.bottom = '-4px'
        RightBottomSide.style.right = '-4px'
        RightBottomSide.style.position = 'absolute'
        RightBottomSide.style.backgroundColor = '#fff'
        RightBottomSide.style.zIndex = '522'
        RightBottomSide.style.opacity = '1'
        // 下右边线
        const BottomRightSide = document.createElement('div')
        BottomRightSide.style.width = '4px'
        BottomRightSide.style.height = '30px'
        BottomRightSide.style.bottom = '-4px'
        BottomRightSide.style.right = '-4px'
        BottomRightSide.style.position = 'absolute'
        BottomRightSide.style.backgroundColor = '#fff'
        BottomRightSide.style.zIndex = '522'
        BottomRightSide.style.opacity = '1'
        // 一起生成
        box.appendChild(verticalLeft)
        box.appendChild(verticalRight)
        box.appendChild(verticalTop)
        box.appendChild(verticalBottom)
        box.appendChild(LeftTopSide)
        box.appendChild(TopListSide)
        box.appendChild(RightTopSide)
        box.appendChild(TopRightSide)
        box.appendChild(LeftBottomSide)
        box.appendChild(BottomListSide)
        box.appendChild(RightBottomSide)
        box.appendChild(BottomRightSide)
      }
    },

    //
    /**
     * 载入文件
     * template:
     *    <h5-cropper hide-input ref="cropper">
     *
     * javascript:
     *    this.$refs.cropper.loadFile()
     *
     * @param file
     */
    loadFile(file) {
      if (file instanceof File) {
        this.onloadimg(file).then((base64) => {
          this.img = base64
          setTimeout(() => {
            this.config.autoCrop = true
            this.addsolide()
          }, 10)
        })
      } else {
        throw new Error('Arguments file is not File')
      }
    },
    /**
     *
     * @param base64
     */
    loadBase64(base64) {
      if (typeof base64 !== 'string') {
        throw new Error('Arguments base64 is not string')
      }
      const base = base64.split(',')
      if (!/^data:image\/(.*?);base64$/.test(base[0])) {
        throw new Error('Arguments base64 MIME is not image/*')
      }

      // Base64 Regex
      if (
        !/^[\/]?([\da-zA-Z]+[\/+]+)*[\da-zA-Z]+([+=]{1,2}|[\/])?$/.test(base[1])
      ) {
        throw new Error('Not standard base64')
      }

      this.img = base64
      setTimeout(() => {
        this.config.autoCrop = true
        this.addsolide()
      }, 10)
    }
  }
}
</script>
<style scoped>
.upbtn {
  width: 100%;
  height: 100%;
}
.bg {
  position: fixed;
  top: 0;
  height: 100vh;
  width: 100%;
  background-color: #000;
  left: 0;
  z-index: 521;
}
.btn {
  height: 8vw;
  padding: 0;
  line-height: 8vw;
  font-size: 4vw;
  padding: 0 3.5vw;
  /* width: 16vw; */
  border-radius: 1.333vw;
  text-align: center;
  /* background-color: #ed594c; */
  /* margin-top: 2.667vw; */
}
.btn1 {
  height: 8vw;
  line-height: 8vw;
  font-size: 4vw;
  padding: 0 4vw;
  /* width: 16vw; */
  border-radius: 1.333vw;
  text-align: center;
  background-color: #5b6e96;
  /* margin-top: 2.667vw; */
}
.img {
  height: 8vw;
  width: 8vw;
  position: absolute;
  left: calc(50% - 4vw);
  /* top: 2.667vw; */
  background-image: url("");
  background-size: 100% 100%;
}
.btndiv {
  height: 13.333vw;
  color: #fff;
  justify-content: space-between;
  display: flex;
  align-items: center;
  padding: 0 4vw;
  line-height: 13.333vw;
  font-size: 4vw;
  position: relative;
}
.wrapper /deep/ .crop-point {
  opacity: 0;
  z-index: 523;
}
.wrapper /deep/ .cropper-view-box {
  outline: 1px solid #fff;
  border: 1px solid #fff;
}
.wrapper /deep/ .vue-cropper {
  background-color: #000;
  background-image: none;
}
.wrapper {
  height: calc(100vh - 21.333vw);
  padding: 4vw;
}
</style>
